<?php

namespace Payment\Notify;

use Payment\Common\PayException;
use Payment\Common\MiConfig;
use Payment\Config;
use Payment\Utils\ArrayUtil;
use Payment\Utils\StrUtil;


/**
 * Class MiNotify
 * 微信回调处理
 * @package Payment\Notify
 * @anthor yeran
 */
class MiNotify extends NotifyStrategy
{

    /**
     * MiNotify constructor.
     * @param array $config
     * @throws PayException
     */
    public function __construct(array $config)
    {
        parent::__construct($config);

        try {
            $this->config = new MiConfig($config);
        } catch (PayException $e) {
            throw $e;
        }
    }

    /**
     * 获取返回的异步通知数据
     * @return array|bool
     * @author yeran
     */
    public function getNotifyData()
    {
        $params = array();
//        foreach($_POST as $key=>$val) {//动态遍历获取所有收到的参数,此步非常关键
//            $params[$key] = $val;
//        }

        //支持直接读取input流
        $data = @file_get_contents('php://input');
        if(!empty($data)){
            $inputArray = json_decode($data,true);
            $params = array_merge($params,$inputArray);
        }

        if(count($params)<1){//如果参数为空,则不进行处理
            return false;
        }

        if(!$this->checkNotifyData($params)){
            return false;
        }

        return $params;
    }

    /**
     * 检查异步通知的数据是否正确
     * @param array $data
     *
     * @author yeran
     * @return boolean
     */
    public function checkNotifyData(array $data)
    {
        // 检查返回数据签名是否正确
        return $this->verifySign($data);
    }

    /**
     * 检查微信返回的数据是否被篡改过
     * @param array $retData
     * @return boolean
     * @author yeran
     */
    protected function verifySign(array $retData)
    {
        $basePath = dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'CacertFile' . DIRECTORY_SEPARATOR;
        $this->config->publicKeyPath = "{$basePath}mipay".DIRECTORY_SEPARATOR."meepay_public_key.pem";

        if(ArrayUtil::SignVerify($retData, $this->config->publicKeyPath)){//验签成功
            //此处进行业务逻辑处理
           return true;
        }
        else{
            return false;
        }

    }

    /**
     *
     * 封装回调函数需要的数据格式
     *
     * @param array $data
     *
     * @return array
     * @author yeran
     */
    protected function getRetData(array $data)
    {
        if ($this->config->returnRaw) {
            $data['channel'] = Config::MI_CHARGE;
            return $data;
        }

        $retData = [
//            'bank_type' => $data['bank_type'],
            'cash_fee' => $data['cash_fee'],
//            'device_info' => $data['device_info'],
            'fee_type' => $data['fee_type'],
//            'is_subscribe' => $data['is_subscribe'],
            'appid'      => $data['sub_appid'],
            'sub_merchant_id' => $data['sub_merchant_id'],
            'buyer_id'   => $data['sub_openid'],
            'order_no'   => $data['out_trade_sn'],//平台
            'meepay_trade_no' => $data['meepay_trade_no'],//米付
            'pay_time'   => date('Y-m-d H:i:s', $data['pay_time']),// 支付完成时间
            'amount'   => $data['total_amount'],
            'trade_type' => $data['trade_type'],
            'transaction_id'   => $data['transaction_id'],//微信
            'trade_state'   => strtolower($data['result_code']),
            'channel'   => Config::MI_CHARGE,
        ];

        // 检查是否存在用户自定义参数
        if (isset($data['attach']) && ! empty($data['attach'])) {
            $retData['return_param'] = $data['attach'];
        }


        return $retData;
    }

    /**
     * 处理完后返回的数据格式
     * @param bool $flag
     * @param string $msg 通知信息，错误原因
     * @author yeran
     * @return string
     */
    protected function replyNotify($flag, $msg = 'OK')
    {
        // 默认为成功
        $return_code ='SUCCESS';
        if (! $flag) {
            $return_code ='FAIL';
        }

        return $return_code;
    }
}
